{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "aa2e4970",
   "metadata": {},
   "source": [
    "# 第九讲 列表（三）\n",
    "\n",
    "## 1. 操作列表\n",
    "在上两讲中，你学习了如何创建简单的列表，还学习了如何操作列表元素。在本章中，你将学习如何遍历整个列表，无论列表有多长，都只需要几行代码就能做到。循环让你能够对列表的每个元素采取一个或一系列相同的措施，从而高效地处理任意长度的列表，包括包含数千乃至数百万个元素的列表。\n",
    "\n",
    "## 2. 遍历整个列表\n",
    "\n",
    "你经常需要遍历列表的所有元素，对每个元素执行相同的操作。例如：\n",
    "\n",
    "- 在游戏中，可能需要将每个界面元素平移相同的距离\n",
    "- 对于包含数的列表，可能需要对每个元素执行相同的统计运算\n",
    "- 在网站中，可能需要显示文章列表中的每个标题\n",
    "\n",
    "如果需要对列表中的每个元素都执行相同的操作，可使用Python中的for循环。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5e607cd3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "alice\n",
      "david\n",
      "carolina\n"
     ]
    }
   ],
   "source": [
    "# magicians.py\n",
    "magicians = ['alice', 'david', 'carolina']\n",
    "for magician in magicians:\n",
    "    print(magician)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0bb38674",
   "metadata": {},
   "source": [
    "#### 语法解析\n",
    "\n",
    "1. **定义列表**：首先，像上讲那样定义了一个列表\n",
    "2. **定义for循环**：这行代码让Python从列表magicians中取出一个名字，并将其与变量magician相关联\n",
    "3. **执行操作**：让Python打印前面赋给变量magician的名字\n",
    "\n",
    "**解读方式**：对于(for)列表magicians中的每位魔术师(magician)，都打印(print)该魔术师(magician)的名字。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1857b235",
   "metadata": {},
   "source": [
    "## 3 深入研究循环\n",
    "\n",
    "循环很重要，因为它是让计算机自动完成重复工作的常见方式之一。\n",
    "\n",
    "**执行步骤：**\n",
    "\n",
    "1. **第一次循环**：\n",
    "\n",
    "   ```python\n",
    "   for magician in magicians:\n",
    "   ```\n",
    "\n",
    "   - Python获取列表magicians中的第一个值'alice'\n",
    "   - 将其与变量magician相关联\n",
    "\n",
    "2. **执行操作**：\n",
    "\n",
    "   ```python\n",
    "   print(magician)\n",
    "   ```\n",
    "\n",
    "   - Python打印magician的值，依然是'alice'\n",
    "\n",
    "3. **继续循环**：\n",
    "\n",
    "   - Python返回循环的第一行\n",
    "   - 获取列表中的下一个名字'david'，并将其与变量magician相关联\n",
    "   - 再执行print(magician)\n",
    "\n",
    "4. **循环结束**：\n",
    "\n",
    "   - 处理完最后一个值'carolina'后\n",
    "   - 列表中没有其他值，Python接着执行程序的下一行代码\n",
    "\n",
    "#### 重要特点\n",
    "\n",
    "- **高效处理**：不管列表包含多少个元素，每个元素都将被执行循环指定的步骤\n",
    "- **处理速度**：如果列表包含100万个元素，Python就将重复执行指定的步骤100万次，而且通常速度非常快\n",
    "\n",
    "#### 命名约定\n",
    "\n",
    "在编写for循环时，可以给将依次与列表中的每个值相关联的临时变量指定任意名称。然而，选择描述单个列表元素的有意义的名称大有裨益。\n",
    "\n",
    "**推荐命名方式：**\n",
    "\n",
    "```python\n",
    "for cat in cats:\n",
    "for dog in dogs:\n",
    "for item in list_of_items:\n",
    "```\n",
    "\n",
    "这些命名约定有助于你明白for循环将对每个元素执行的操作。使用单数和复数形式的名称，可帮助你判断代码段处理的是单个列表元素还是整个列表。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3cda95d1",
   "metadata": {},
   "source": [
    "## 4. 在for循环中执行更多的操作\n",
    "\n",
    "在for循环中，可以对每个元素执行任意操作。下面来扩展前面的示例，为每位魔术师打印一条消息，指出他/她的表演太精彩了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8e8b5cc8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Alice, that was a great trick!\n",
      "David, that was a great trick!\n",
      "Carolina, that was a great trick!\n"
     ]
    }
   ],
   "source": [
    "# magicians.py\n",
    "magicians = ['alice', 'david', 'carolina']\n",
    "for magician in magicians:\n",
    "    print(f\"{magician.title()}, that was a great trick!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f2d36403",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Alice, that was a great trick!\n",
      "I can't wait to see your next trick, Alice.\n",
      "\n",
      "David, that was a great trick!\n",
      "I can't wait to see your next trick, David.\n",
      "\n",
      "Carolina, that was a great trick!\n",
      "I can't wait to see your next trick, Carolina.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 可以在for循环中包含任意多行代码。下面再添加一行代码，告诉每位魔术师，我们期待他/她的下一次表演：\n",
    "\n",
    "magicians = ['alice', 'david', 'carolina']\n",
    "for magician in magicians:\n",
    "    print(f\"{magician.title()}, that was a great trick!\")\n",
    "    print(f\"I can't wait to see your next trick, {magician.title()}.\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36586b94",
   "metadata": {},
   "source": [
    "#### 重要说明\n",
    "\n",
    "- 两个函数调用print()都缩进了，因此它们都将针对列表中的每位魔术师执行一次\n",
    "- 第二个函数调用print()中的换行符\"\\n\"在每次循环结束后都插入一个空行，从而整洁地将针对各位魔术师的消息编组"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04cb640a",
   "metadata": {},
   "source": [
    "## 5. 在for循环结束后执行一些操作\n",
    "\n",
    "for循环结束后怎么办呢？通常，你想提供总结性输出或接着执行程序必须完成的其他任务。\n",
    "\n",
    "在for循环后面，**没有缩进的代码都只执行一次，不会重复执行**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "96bf8bd5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Alice, that was a great trick!\n",
      "I can't wait to see your next trick, Alice.\n",
      "\n",
      "David, that was a great trick!\n",
      "I can't wait to see your next trick, David.\n",
      "\n",
      "Carolina, that was a great trick!\n",
      "I can't wait to see your next trick, Carolina.\n",
      "\n",
      "Thank you, everyone. That was a great magic show!\n"
     ]
    }
   ],
   "source": [
    "magicians = ['alice', 'david', 'carolina']\n",
    "for magician in magicians:\n",
    "    print(f\"{magician.title()}, that was a great trick!\")\n",
    "    print(f\"I can't wait to see your next trick, {magician.title()}.\\n\")\n",
    "\n",
    "print(\"Thank you, everyone. That was a great magic show!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52e8d08b",
   "metadata": {},
   "source": [
    "#### 实际应用\n",
    "\n",
    "使用for循环处理数据，是一种对数据集执行整体操作的不错方式。例如：\n",
    "\n",
    "- 你可能使用for循环来初始化游戏——遍历角色列表，将每个角色都显示到屏幕上\n",
    "- 然后在循环后面添加一些代码，在屏幕上绘制所有角色后显示一个Play Now按钮"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a1d9eea",
   "metadata": {},
   "source": [
    "## 6. 避免缩进错误\n",
    "Python根据缩进来判断代码行与程序其他部分的关系。Python通过缩进让代码更易读。简单地说，它要求你使用缩进让代码整洁且结构清晰。\n",
    "\n",
    "当你开始编写必须正确缩进的代码时，需要注意一些常见的缩进错误。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "fda5dc8c",
   "metadata": {},
   "outputs": [
    {
     "ename": "IndentationError",
     "evalue": "expected an indented block after 'for' statement on line 4 (2388035737.py, line 5)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  Cell \u001b[1;32mIn [6], line 5\u001b[1;36m\u001b[0m\n\u001b[1;33m    print(magician)  # 这行应该缩进但没有缩进\u001b[0m\n\u001b[1;37m    ^\u001b[0m\n\u001b[1;31mIndentationError\u001b[0m\u001b[1;31m:\u001b[0m expected an indented block after 'for' statement on line 4\n"
     ]
    }
   ],
   "source": [
    "# 忘记缩进\n",
    "\n",
    "magicians = ['alice', 'david', 'carolina']\n",
    "for magician in magicians:\n",
    "print(magician)  # 这行应该缩进但没有缩进"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "8ddf0e23",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Alice, that was a great trick!\n",
      "David, that was a great trick!\n",
      "Carolina, that was a great trick!\n",
      "I can't wait to see your next trick, Carolina.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 忘记缩进额外的代码行\n",
    "magicians = ['alice', 'david', 'carolina']\n",
    "for magician in magicians:\n",
    "    print(f\"{magician.title()}, that was a great trick!\")\n",
    "print(f\"I can't wait to see your next trick, {magician.title()}.\\n\")  # 这行应该缩进"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a0d98ded",
   "metadata": {},
   "outputs": [
    {
     "ename": "IndentationError",
     "evalue": "unexpected indent (2047411767.py, line 4)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  Cell \u001b[1;32mIn [8], line 4\u001b[1;36m\u001b[0m\n\u001b[1;33m    print(message)  # 这行不应该缩进\u001b[0m\n\u001b[1;37m    ^\u001b[0m\n\u001b[1;31mIndentationError\u001b[0m\u001b[1;31m:\u001b[0m unexpected indent\n"
     ]
    }
   ],
   "source": [
    "# 不必要的缩进\n",
    "\n",
    "message = \"Hello Python world!\"\n",
    "    print(message)  # 这行不应该缩进"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "2d48f193",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Alice, that was a great trick!\n",
      "I can't wait to see your next trick, Alice.\n",
      "\n",
      "Thank you everyone, that was a great magic show!\n",
      "David, that was a great trick!\n",
      "I can't wait to see your next trick, David.\n",
      "\n",
      "Thank you everyone, that was a great magic show!\n",
      "Carolina, that was a great trick!\n",
      "I can't wait to see your next trick, Carolina.\n",
      "\n",
      "Thank you everyone, that was a great magic show!\n"
     ]
    }
   ],
   "source": [
    "# 循环后不必要的缩进\n",
    "\n",
    "magicians = ['alice', 'david', 'carolina']\n",
    "for magician in magicians:\n",
    "    print(f\"{magician.title()}, that was a great trick!\")\n",
    "    print(f\"I can't wait to see your next trick, {magician.title()}.\\n\")\n",
    "    print(\"Thank you everyone, that was a great magic show!\")  # 这行不应该缩进"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "3b5d8b25",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "expected ':' (264423871.py, line 4)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  Cell \u001b[1;32mIn [10], line 4\u001b[1;36m\u001b[0m\n\u001b[1;33m    for magician in magicians  # 遗漏了冒号\u001b[0m\n\u001b[1;37m                               ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m expected ':'\n"
     ]
    }
   ],
   "source": [
    "# 遗漏冒号\n",
    "\n",
    "magicians = ['alice', 'david', 'carolina']\n",
    "for magician in magicians  # 遗漏了冒号\n",
    "    print(magician)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a947b26",
   "metadata": {},
   "source": [
    "## 7. 创建数值列表\n",
    "需要存储一组数的原因很多。例如，在游戏中，需要跟踪每个角色的位置，还可能需要跟踪玩家的几个最高得分；在数据可视化中，处理的几乎都是由数（如温度、距离、人口数量、经度和纬度等）组成的集合。\n",
    "\n",
    "列表非常适合用于存储数值集合，而 Python 提供了很多工具，可帮助你高效地处理数值列表。明白如何有效地使用这些工具后，即便列表包含数百万个元素，你编写的代码也能运行得很好。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6d918897",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "# 使用 range() 函数\n",
    "\n",
    "for value in range(1, 5):   #计头不计尾\n",
    "    print(value)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "64d1dbce",
   "metadata": {},
   "source": [
    "在这个示例中，range() 只打印数 1～4，这是编程语言中常见的差一行为的结果。range() 函数让 Python 从指定的第一个值开始数，并在到达指定的第二个值时停止，因此输出不包含第二个值（这里为5）。\n",
    "\n",
    "要打印数 1～5，需要使用 range(1,6)。\n",
    "\n",
    "在使用 range() 时，如果输出不符合预期，请尝试将指定的值加1或减1。\n",
    "\n",
    "在调用 range() 函数时，也可只指定一个参数，这样它将从0开始，例如，range(6) 返回数 0～5（含）。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68d2b33f",
   "metadata": {},
   "source": [
    "### 7.1 使用range()创建数值列表\n",
    "\n",
    "要创建数值列表，可使用 list() 函数将 range() 的结果直接转换为列表。如果将 range() 作为 list() 的参数，输出将是一个数值列表。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a7fc8924",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "numbers = list(range(1, 6)) #list函数将 range() 的结果直接转换为列表\n",
    "print(numbers)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b020ff57",
   "metadata": {},
   "source": [
    "在使用 range() 函数时，还可指定步长。为此，可以给这个函数指定第三个参数，Python 将根据这个步长来生成数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6dbea3ef",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 4, 6, 8, 10]\n"
     ]
    }
   ],
   "source": [
    "# 打印1-10的偶数\n",
    "even_numbers = list(range(2, 11, 2)) #range(2, 11, 2) 生成从2开始，步长为2的数，直到11（不包含11）\n",
    "print(even_numbers)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "60d91515",
   "metadata": {},
   "source": [
    "使用 range() 函数几乎能够创建任意数值集合。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "695c3589",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n"
     ]
    }
   ],
   "source": [
    "squares = []\n",
    "for value in range(1, 11):\n",
    "    squares.append(value**2)\n",
    "print(squares)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea96649b",
   "metadata": {},
   "source": [
    "### 7.2 对数值列表执行简单的统计计算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "c625644c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0, 9, 45)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "digits=[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n",
    "min(digits), max(digits), sum(digits)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "236a2e7e",
   "metadata": {},
   "source": [
    "### 列表推导式\n",
    "\n",
    "列表推导式（list comprehension）将 for 循环和创建新元素的代码合并成一行，并自动追加新元素。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7f7e34f4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n"
     ]
    }
   ],
   "source": [
    "squares = [value**2 for value in range(1, 11)]\n",
    "print(squares)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74c4c5b4",
   "metadata": {},
   "source": [
    "## 8. 使用列表的一部分\n",
    "\n",
    "### 8.1 切片\n",
    "\n",
    "要创建切片，可指定要使用的第一个元素和最后一个元素的索引。与range() 函数一样，Python 在到达指定的第二个索引之前的元素时停止。\n",
    "\n",
    "要输出列表中的前三个元素，需要指定索引 0 和 3，这将返回索引分别为 0、1 和 2 的元素。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "60b99317",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['charles', 'martina', 'michael']\n"
     ]
    }
   ],
   "source": [
    "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n",
    "print(players[0:3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "af148724",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['martina', 'michael', 'florence']\n"
     ]
    }
   ],
   "source": [
    "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n",
    "print(players[1:4])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c70c3a44",
   "metadata": {},
   "source": [
    "如果没有指定第一个索引，Python 将自动从列表开头开始："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "7df62679",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['charles', 'martina', 'michael', 'florence']\n"
     ]
    }
   ],
   "source": [
    "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n",
    "print(players[:4])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3328a3d4",
   "metadata": {},
   "source": [
    "要让切片终止于列表末尾，也可使用类似的语法。例如，如果要提取从第三个元素到列表末尾的所有元素，可将起始索引指定为 2，并省略终止索引："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "7ae694b1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['michael', 'florence', 'eli']\n"
     ]
    }
   ],
   "source": [
    "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n",
    "print(players[2:])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "728c54f3",
   "metadata": {},
   "source": [
    "负数索引返回与列表末尾有相应距离的元素，因此可以输出列表末尾的任意切片。如果要输出名单上最后三名队员的名字，可使用切片 players[-3:]："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "4958c476",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['michael', 'florence', 'eli']\n"
     ]
    }
   ],
   "source": [
    "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n",
    "print(players[-3:])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6a1b027",
   "metadata": {},
   "source": [
    "### 8.2 遍历切片\n",
    "\n",
    "如果要遍历列表的部分元素，可在 for 循环中使用切片。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "ffc2cd10",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Here are the first three players on my team:\n",
      "Charles\n",
      "Martina\n",
      "Michael\n"
     ]
    }
   ],
   "source": [
    "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n",
    "\n",
    "print(\"Here are the first three players on my team:\")\n",
    "\n",
    "for player in players[:3]:\n",
    "    print(player.title())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "46e90c2d",
   "metadata": {},
   "source": [
    "### 8.3 复制列表\n",
    "要复制列表，可以创建一个包含整个列表的切片，方法是同时省略起始索引和终止索引（[:]）。这让 Python 创建一个起始于第一个元素、终止于最后一个元素的切片，即复制整个列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "590f32ec",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "My favorite foods are:\n",
      "['pizza', 'falafel', 'carrot cake']\n",
      "\n",
      "My friend's favorite foods are:\n",
      "['pizza', 'falafel', 'carrot cake']\n"
     ]
    }
   ],
   "source": [
    "my_foods = ['pizza', 'falafel', 'carrot cake']\n",
    "\n",
    "friend_foods = my_foods[:]\n",
    "\n",
    "print(\"My favorite foods are:\")\n",
    "print(my_foods)\n",
    "\n",
    "print(\"\\nMy friend's favorite foods are:\")\n",
    "print(friend_foods)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "684c5772",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "My favorite foods are:\n",
      "['pizza', 'falafel', 'carrot cake', 'cannoli']\n",
      "\n",
      "My friend's favorite foods are:\n",
      "['pizza', 'falafel', 'carrot cake', 'ice cream']\n"
     ]
    }
   ],
   "source": [
    "my_foods = ['pizza', 'falafel', 'carrot cake']\n",
    "\n",
    "friend_foods = my_foods[:]\n",
    "\n",
    "my_foods.append('cannoli')\n",
    "\n",
    "friend_foods.append('ice cream')\n",
    "\n",
    "print(\"My favorite foods are:\")\n",
    "print(my_foods)\n",
    "\n",
    "print(\"\\nMy friend's favorite foods are:\")\n",
    "print(friend_foods)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b69e0b95",
   "metadata": {},
   "source": [
    "如果只是将 my_foods 赋给 friend_foods，就不能得到两个列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "7afc0ee9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "My favorite foods are:\n",
      "['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']\n",
      "\n",
      "My friend's favorite foods are:\n",
      "['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']\n"
     ]
    }
   ],
   "source": [
    "my_foods = ['pizza', 'falafel', 'carrot cake']\n",
    "\n",
    "# 这是行不通的\n",
    "friend_foods = my_foods\n",
    "\n",
    "my_foods.append('cannoli')\n",
    "\n",
    "friend_foods.append('ice cream')\n",
    "\n",
    "print(\"My favorite foods are:\")\n",
    "print(my_foods)\n",
    "\n",
    "print(\"\\nMy friend's favorite foods are:\")\n",
    "print(friend_foods)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6787ac29",
   "metadata": {},
   "source": [
    "## 9. 元组\n",
    "\n",
    "列表非常适合用于存储在程序运行期间可能变化的数据集。列表是可以修改的，这对于处理网站的用户列表或游戏中的角色列表至关重要。然而，你有时候需要创建一系列不可修改的元素，元组可满足这种需求。Python 将不能修改的值称为不可变的，而不可变的列表称为元组（tuple）。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e3c8b93",
   "metadata": {},
   "source": [
    "### 9.1 定义元组\n",
    "\n",
    "元组看起来很像列表，但使用圆括号而不是方括号来标识。定义元组后，就可使用索引来访问其元素，就像访问列表元素一样。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "5a490f9a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "200\n",
      "50\n"
     ]
    }
   ],
   "source": [
    "dimensions = (200, 50)\n",
    "\n",
    "print(dimensions[0])\n",
    "\n",
    "print(dimensions[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9891fd4",
   "metadata": {},
   "source": [
    "下面来尝试修改元组 dimensions 的一个元素，看看结果如何："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "4541a60e",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'tuple' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mTypeError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[18]\u001b[39m\u001b[32m, line 3\u001b[39m\n\u001b[32m      1\u001b[39m dimensions = (\u001b[32m200\u001b[39m, \u001b[32m50\u001b[39m)\n\u001b[32m----> \u001b[39m\u001b[32m3\u001b[39m \u001b[43mdimensions\u001b[49m\u001b[43m[\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m]\u001b[49m = \u001b[32m250\u001b[39m\n",
      "\u001b[31mTypeError\u001b[39m: 'tuple' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "dimensions = (200, 50)\n",
    "\n",
    "dimensions[0] = 250"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b7de416",
   "metadata": {},
   "source": [
    "严格地说，元组是由逗号标识的，圆括号只是让元组看起来更整洁、更清晰。如果你要定义只包含一个元素的元组，必须在这个元素后面加上逗号："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2637993f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3,)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_t = (3,)\n",
    "\n",
    "my_t"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b76141cc",
   "metadata": {},
   "source": [
    "### 9.2 遍历元组中的所有值\n",
    "\n",
    "像列表一样，也可以使用 for 循环来遍历元组中的所有值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "0a3c4053",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "200\n",
      "50\n"
     ]
    }
   ],
   "source": [
    "dimensions = (200, 50)\n",
    "\n",
    "for dimension in dimensions:\n",
    "    print(dimension)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "robinlaw",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
